import { get, post } from "@/api/fetchMethod";
import { useEffect, useState } from "react";

type Methods = "GET" | "POST";
/**
 * useFetchData的返回类型
 */
interface IUseFetchData<Res> {
  loading: boolean;
  data: Res | undefined;
  error: unknown;
}
/**
 * useFetchData的参数类型
 */
interface IUserParams<T> {
  url: string;
  params?: T;
  method?: Methods;
}

const methodMap = new Map<Methods, (...args: any[]) => Promise<any>>([
  ["GET", get],
  ["POST", post]
]);

/**
 * 封装请求方法
 * @param url url地址
 * @param params 请求参数
 * @returns loading、data-响应数据、error-错误信息
 */
function useFetchData<Req, Res>({ url, params, method = "GET" }: IUserParams<Req>): IUseFetchData<Res> {
  const [loading, setLoading] = useState(false);
  const [data, setData] = useState<Res>();
  const [error, setError] = useState<unknown>();

  useEffect(() => {
    let isMounted = true;

    const fetchData = async () => {
      isMounted && setLoading(true);
      try {
        const result = await methodMap.get(method)!(url, params);
        // 组件卸载不执行
        isMounted && setData(result);
      } catch (error) {
        isMounted && setError(error);
      } finally {
        isMounted && setLoading(false);
      }
    };

    fetchData();

    return () => {
      isMounted = false;
    };
  }, [url, params, method]);

  return {
    loading,
    data,
    error
  };
}

export default useFetchData;
